<?php
class Gmapsprofile_Api_Core extends Core_Api_Abstract
{
  protected $_requireProfileType = true; 
 
  public function geocoding($user_hook_id = 0, $limit = 0)
  {  
    $count_line = 0;
    // Get table info
	$mName = Engine_Api::_()->getDbtable('markers', 'gmapsprofile')->info('name');
    $table = Engine_Api::_()->getItemTable('user');
    $userTableName = $table->info('name');  
    // Contruct query
    $select = $table->select()
      ->setIntegrityCheck(false)
      ->from($userTableName)
      ->joinLeft($mName, "`{$userTableName}`.`user_id` = `{$mName}`.`user_id`", array($mName.".lat AS lat", $mName.".lng AS lng"));
	  
	if ($user_hook_id) {
	  $select
	    ->where("`{$userTableName}`.`user_id` = ? ", $user_hook_id);
	}    
	else {
	  $select
	  ->where("`{$mName}`.`lat` IS NULL")
	  ->where("`{$mName}`.`lng` IS NULL");
	}
	
	$user_info = $table->fetchAll($select);
	
	if (count($user_info) <= 0)	return "exit";
	
	// Initialize delay in geocode speed
	$delay = 0;
	$base_url = "http://maps.google.com/maps/geo?output=xml";

	foreach ($user_info as $latLng) {
	  $geocode_pending = true;
	  if ($limit > 0 && $limit <= $count_line) return $count_line;
	  while ($geocode_pending) {
	    //if (!empty($latLng->lat) && !empty($latLng->lng)) continue;
	    $user = Engine_Api::_()->getItem('user', $latLng->user_id);
	    $address = $this->membersAddress($user);
	    if (empty($address['location'])) { $geocode_pending = false; continue; }
    
		    $request_url = $base_url . "&q=" . urlencode($address['location']);
		    $xml = simplexml_load_file($request_url)/* or die("url not loading")*/;
	
		    $status = $xml->Response->Status->code;
		    if (strcmp($status, "200") == 0) {
		      // Successful geocode
		      $geocode_pending = false;
		      $coordinates = $xml->Response->Placemark->Point->coordinates;
		      $coordinatesSplit = explode(",", $coordinates);
		      // Format: Longitude, Latitude, Altitude
		      $lat = $coordinatesSplit[1];
		      $lng = $coordinatesSplit[0];
	

      		  $insert_marker = Engine_Api::_()->getDbtable('markers', 'gmapsprofile');
		      $db = $insert_marker->getAdapter();
		      $db->beginTransaction();

		      try
		      { 
	          $line = $insert_marker->createRow();
	          $line->user_id = $latLng->user_id;
	          $line->lat = $lat;
	          $line->lng = $lng;
			  $line->address = $address['territories'];
			  $line->save();
			
	          // Commit
	          $db->commit();
 			  $count_line++;
		      }

		      catch( Exception $e )
		      {
		        $db->rollBack();
		        throw $e;
		      }
		    } else if (strcmp($status, "620") == 0) {
		      // sent geocodes too fast
		      $delay += 100000;
		    } else {
		      // failure to geocode
		      $geocode_pending = false;
		    }
		    usleep($delay);
		  }
	} 
	return $count_line;
  }

  public function membersAddress($subject, $_fieldType = 'user')
  {
	$user = $subject;
	$settings = Engine_Api::_()->getApi('settings', 'core');
    // Set data
    $mapData = Engine_Api::_()->getApi('core', 'fields')->getFieldsMaps($_fieldType);
    $metaData = Engine_Api::_()->getApi('core', 'fields')->getFieldsMeta($_fieldType);
    $optionsData = Engine_Api::_()->getApi('core', 'fields')->getFieldsOptions($_fieldType);
	$valueData = Engine_Api::_()->fields()->getFieldsValues($user);
	$profile_type = Engine_Api::_()->fields()->getFieldsSearch($user);
	
	if ($profile_type['profile_type'] == "")
	  return $profile_type['profile_type'];

    // Get top level fields
    $topLevelMaps = $mapData->getRowsMatching(array('field_id' => 0, 'option_id' => 0));
    $topLevelFields = array();
    foreach( $topLevelMaps as $map ) {
      $field = $map->getChild();
      $topLevelFields[$field->field_id] = $field;
    } 
  
    // Do we require profile type?
    // No
    if( !$this->_requireProfileType ) {
      $this->topLevelOptionId = '0';
      $this->topLevelFieldId = '0';
    }
    // Yes
    else {
      // Get top level field
      // Only allow one top level field
      if( count($topLevelFields) > 1 ) {
        throw new Engine_Exception('Only one top level field is currently allowed');
      }
      $topLevelField = array_shift($topLevelFields);
      // Only allow the "profile_type" field to be a top level field (for now)
      if( $topLevelField->type !== 'profile_type' ) {
        throw new Engine_Exception('Only profile_type can be a top level field');
      }

      // Get top level options
      $topLevelOptions = array();
      foreach( $optionsData->getRowsMatching('field_id', $topLevelField->field_id) as $option ) {
        $topLevelOptions[$option->option_id] = $option->label;
      }
	  $this->view->topLevelOptions = $topLevelOptions;

      // Get selected option
	  
      $option_id = $profile_type['profile_type'];
      if( empty($option_id) || empty($topLevelOptions[$option_id]) ) {
        $option_id = current(array_keys($topLevelOptions));
      }
      $topLevelOption = $optionsData->getRowMatching('option_id', $option_id);

      if( !$topLevelOption ) {
        throw new Engine_Exception('Missing option');
      }
      $this->view->topLevelOption = $topLevelOption;
      $this->view->topLevelOptionId = $topLevelOption->option_id;
	  $level = 'gmapsprofile_level_' . $option_id;	
	  $fields_address = isset($settings->$level) ? explode(';', $settings->$level) : '';
      // Get second level fields
      $secondLevelMaps = array();
      if( !empty($option_id) ) {
        $secondLevelMaps = $mapData->getRowsMatching('option_id', $option_id);
        if( !empty($secondLevelMaps) ) {
		  $prefix = ' ';
		  $location = '';	
		  $territories_user = '';	
          foreach( $secondLevelMaps as $map ) {
            $oField = $map->getChild();
			$locale = Zend_Registry::get('Zend_Translate')->getLocale();			
			$territories = Zend_Locale::getTranslationList('territory', $locale, 2);
	  		if ($oField) {
			  if (!empty($settings->$level) && in_array($oField->field_id, $fields_address))	{
			      $options = $optionsData->getRowMatching('field_id', $oField->field_id);
			      $Data = $options ? $options->label : $valueData->getRowMatching('field_id', $oField->field_id)->value;
				  if( !empty($Data) && isset($territories[$Data]) ) {
					$location .= !empty($Data) ? $prefix . $Data : '';
					$territories_user .= !empty($territories[$Data]) ? $prefix . $territories[$Data] : '';
					if ( !empty($Data) ) $prefix = ', ';
				  }	
				  else {
			        $location .= !empty($Data) ? $prefix . $Data : '';
					$territories_user .= !empty($Data) ? $prefix . $Data : '';
					if ( !empty($Data) ) $prefix = ', ';
				  }
			  }			
			  elseif (empty($settings->$level)) {
			    switch ($oField->type) {
				case 'location': 
			      $Data = $valueData->getRowMatching('field_id', $oField->field_id);
			      $location .= !empty($Data->value) ?  $prefix .$Data->value : '';
				  $territories_user .= !empty($Data->value) ? $prefix . $Data->value : '';
				  $prefix = ', ';
			      break;
				case 'city':
			      $Data = $valueData->getRowMatching('field_id', $oField->field_id);
			      $location .= !empty($Data->value) ?  $prefix .$Data->value : '';
				  $territories_user .= !empty($Data->value) ? $prefix . $Data->value : '';
				  $prefix = ', ';
			      break;
				case 'country':
			      $Data = $valueData->getRowMatching('field_id', $oField->field_id);
				  if( !empty($Data->value) && isset($territories[$Data->value]) ) {
					$location .= !empty($Data->value) ? $prefix . $Data->value : '';
					$territories_user .= !empty($territories[$Data->value]) ? $prefix . $territories[$Data->value] : '';
					if ( !empty($Data->value) ) $prefix = ', ';
				  }	
				  else {
			        $location .= !empty($Data->value) ? $prefix . $Data->value : '';
					$territories_user .= !empty($Data->value) ? $prefix . $Data->value : '';
					if ( !empty($Data->value) ) $prefix = ', ';
				  }
			      break;	
				case 'zip_code':
			      $Data = $valueData->getRowMatching('field_id', $oField->field_id);
			      $location .= !empty($Data->value) ?  $prefix .$Data->value : '';
				  $territories_user .= !empty($Data->value) ? $prefix . $Data->value : '';
				  $prefix = ', ';
			      break;				  		  
				}  
			  }			
       		}
          }
        }
      }
    } 
	return array('location' => $location, 'territories' => $territories_user);
  } 
  
  public function addressUser($user_id)
  {
    // Get table info
    $table = Engine_Api::_()->getDbtable('markers', 'gmapsprofile');
    $userTableName = $table->info('name');
    $select = $table->select()
      ->from($userTableName)		
      ->where("{$userTableName}.user_id = ?", $user_id);
	$rawData = $table->fetchRow($select); 
	return array('lat' => $rawData->lat, 'lng' => $rawData->lng);
  }   
  
  public function sameAddress($lat, $lng, $subject)
  {
	if ($subject) {
	  $user = Engine_Api::_()->getItem('user', (int) $subject);
	}
	else 
      $user = Engine_Api::_()->user()->getViewer();

	$select = $user->membership()->getMembersOfSelect();
	$friends = $paginator = Zend_Paginator::factory($select);
	$paginator->setItemCountPerPage(10000000);
	$ids = array();
    foreach( $friends as $friend ) {
      $ids[] = $friend->resource_id;
    }
	
    // Get table info
    $table = Engine_Api::_()->getItemTable('user');
    $userTableName = $table->info('name');
	
	$mName = Engine_Api::_()->getDbtable('markers', 'gmapsprofile')->info('name');	

    $searchTable = Engine_Api::_()->fields()->getTable('user', 'search');
    $searchTableName = $searchTable->info('name');

    $select = $table->select()
      ->setIntegrityCheck(false)
      ->from($userTableName)
      ->joinLeft($searchTableName, "`{$searchTableName}`.`item_id` = `{$userTableName}`.`user_id`", null);
	$select
	  ->joinLeft($mName, $mName.".user_id = engine4_users.user_id", null);

	$select  
      ->where($mName.".lat = ?", $lat)
	  ->where($mName.".lng = ?", $lng)
	  ->where($mName.'.user_id IN(?)', (array) $ids)
      ->where("{$userTableName}.search = ?", 1)
      ->where("{$userTableName}.enabled = ?", 1)
	  ->where($userTableName.'.user_id != ?', "0")
      ->group("{$userTableName}.user_id")
      ->order("{$userTableName}.displayname ASC");

	$rawData = $table->fetchAll($select); 
	return (object) $rawData;
  } 
  
  public function isAddress()
  {
    $table = Engine_Api::_()->getDbtable('markers', 'gmapsprofile');
    $TableName = $table->info('name');
    $select = $table->select()
      ->from($TableName);
	$rawData = $table->fetchAll($select);
	if (count($rawData)) return true; 
	return false;	
  }   
}
